home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 1999-2000 Id Software, Inc.
- //
- // cg_effects.c -- these functions generate localentities, usually as a result
- // of event processing
-
- #include "cg_local.h"
-
-
- /*
- ==================
- CG_BubbleTrail
-
- Bullets shot underwater
- ==================
- */
- void CG_BubbleTrail( vec3_t start, vec3_t end, float spacing ) {
- vec3_t move;
- vec3_t vec;
- float len;
- int i;
-
- VectorCopy (start, move);
- VectorSubtract (end, start, vec);
- len = VectorNormalize (vec);
-
- // advance a random amount first
- i = rand() % (int)spacing;
- VectorMA( move, i, vec, move );
-
- VectorScale (vec, spacing, vec);
-
- for ( ; i < len; i += spacing ) {
- localEntity_t *le;
- refEntity_t *re;
-
- le = CG_AllocLocalEntity();
- le->leFlags = LEF_PUFF_DONT_SCALE;
- le->leType = LE_MOVE_SCALE_FADE;
- le->startTime = cg.time;
- le->endTime = cg.time + 1000 + random() * 250;
- le->lifeRate = 1.0 / ( le->endTime - le->startTime );
-
- re = &le->refEntity;
- re->shaderTime = cg.time / 1000.0f;
-
- re->reType = RT_SPRITE;
- re->rotation = 0;
- re->radius = 3;
- re->customShader = cgs.media.waterBubbleShader;
- re->shaderRGBA[0] = 0xff;
- re->shaderRGBA[1] = 0xff;
- re->shaderRGBA[2] = 0xff;
- re->shaderRGBA[3] = 0xff;
-
- le->color[3] = 1.0;
-
- le->pos.trType = TR_LINEAR;
- le->pos.trTime = cg.time;
- VectorCopy( move, le->pos.trBase );
- le->pos.trDelta[0] = crandom()*5;
- le->pos.trDelta[1] = crandom()*5;
- le->pos.trDelta[2] = crandom()*5 + 6;
-
- VectorAdd (move, vec, move);
- }
- }
-
- /*
- =====================
- CG_SmokePuff
-
- Adds a smoke puff or blood trail localEntity.
- =====================
- */
- localEntity_t *CG_SmokePuff( const vec3_t p, const vec3_t vel,
- float radius,
- float r, float g, float b, float a,
- float duration,
- int startTime,
- int leFlags,
- qhandle_t hShader ) {
- static int seed = 0x92;
- localEntity_t *le;
- refEntity_t *re;
-
- le = CG_AllocLocalEntity();
- le->leFlags = leFlags;
- le->radius = radius;
-
- re = &le->refEntity;
- re->rotation = Q_random( &seed ) * 360;
- re->radius = radius;
- re->shaderTime = startTime / 1000.0f;
-
- le->leType = LE_MOVE_SCALE_FADE;
- le->startTime = startTime;
- le->endTime = startTime + duration;
- le->lifeRate = 1.0 / ( le->endTime - le->startTime );
- le->color[0] = r;
- le->color[1] = g;
- le->color[2] = b;
- le->color[3] = a;
-
-
- le->pos.trType = TR_LINEAR;
- le->pos.trTime = startTime;
- VectorCopy( vel, le->pos.trDelta );
- VectorCopy( p, le->pos.trBase );
-
- VectorCopy( p, re->origin );
- re->customShader = hShader;
-
- // rage pro can't alpha fade, so use a different shader
- if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
- re->customShader = cgs.media.smokePuffRageProShader;
- re->shaderRGBA[0] = 0xff;
- re->shaderRGBA[1] = 0xff;
- re->shaderRGBA[2] = 0xff;
- re->shaderRGBA[3] = 0xff;
- } else {
- re->shaderRGBA[0] = le->color[0] * 0xff;
- re->shaderRGBA[1] = le->color[1] * 0xff;
- re->shaderRGBA[2] = le->color[2] * 0xff;
- re->shaderRGBA[3] = 0xff;
- }
-
- re->reType = RT_SPRITE;
- re->radius = le->radius;
-
- return le;
- }
-
- /*
- ==================
- CG_SpawnEffect
-
- Player teleporting in or out
- ==================
- */
- void CG_SpawnEffect( vec3_t org ) {
- localEntity_t *le;
- refEntity_t *re;
-
- le = CG_AllocLocalEntity();
- le->leFlags = 0;
- le->leType = LE_FADE_RGB;
- le->startTime = cg.time;
- le->endTime = cg.time + 500;
- le->lifeRate = 1.0 / ( le->endTime - le->startTime );
-
- le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
-
- re = &le->refEntity;
-
- re->reType = RT_MODEL;
- re->shaderTime = cg.time / 1000.0f;
-
- re->customShader = cgs.media.teleportEffectShader;
- re->hModel = cgs.media.teleportEffectModel;
- AxisClear( re->axis );
-
- VectorCopy( org, re->origin );
- re->origin[2] -= 24;
- }
-
-
-
-
- /*
- ====================
- CG_MakeExplosion
- ====================
- */
- localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
- qhandle_t hModel, qhandle_t shader,
- int msec, qboolean isSprite ) {
- float ang;
- localEntity_t *ex;
- int offset;
- vec3_t tmpVec, newOrigin;
-
- if ( msec <= 0 ) {
- CG_Error( "CG_MakeExplosion: msec = %i", msec );
- }
-
- // skew the time a bit so they aren't all in sync
- offset = rand() & 63;
-
- ex = CG_AllocLocalEntity();
- if ( isSprite ) {
- ex->leType = LE_SPRITE_EXPLOSION;
-
- // randomly rotate sprite orientation
- ex->refEntity.rotation = rand() % 360;
- VectorScale( dir, 16, tmpVec );
- VectorAdd( tmpVec, origin, newOrigin );
- } else {
- ex->leType = LE_EXPLOSION;
- VectorCopy( origin, newOrigin );
-
- // set axis with random rotate
- if ( !dir ) {
- AxisClear( ex->refEntity.axis );
- } else {
- ang = rand() % 360;
- VectorCopy( dir, ex->refEntity.axis[0] );
- RotateAroundDirection( ex->refEntity.axis, ang );
- }
- }
-
- ex->startTime = cg.time - offset;
- ex->endTime = ex->startTime + msec;
-
- // bias the time so all shader effects start correctly
- ex->refEntity.shaderTime = ex->startTime / 1000.0f;
-
- ex->refEntity.hModel = hModel;
- ex->refEntity.customShader = shader;
-
- // set origin
- VectorCopy( newOrigin, ex->refEntity.origin );
- VectorCopy( newOrigin, ex->refEntity.oldorigin );
-
- ex->color[0] = ex->color[1] = ex->color[2] = 1.0;
-
- return ex;
- }
-
-
- /*
- =================
- CG_Bleed
-
- This is the spurt of blood when a character gets hit
- =================
- */
- void CG_Bleed( vec3_t origin, int entityNum ) {
- localEntity_t *ex;
-
- if ( !cg_blood.integer ) {
- return;
- }
-
- ex = CG_AllocLocalEntity();
- ex->leType = LE_EXPLOSION;
-
- ex->startTime = cg.time;
- ex->endTime = ex->startTime + 500;
-
- VectorCopy ( origin, ex->refEntity.origin);
- ex->refEntity.reType = RT_SPRITE;
- ex->refEntity.rotation = rand() % 360;
- ex->refEntity.radius = 16;
-
- ex->refEntity.customShader = cgs.media.bloodExplosionShader;
-
- // don't show player's own blood in view
- if ( entityNum == cg.snap->ps.clientNum ) {
- ex->refEntity.renderfx |= RF_THIRD_PERSON;
- }
- }
-
-
-
- /*
- ==================
- CG_LaunchGib
- ==================
- */
- void CG_LaunchGib( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
- localEntity_t *le;
- refEntity_t *re;
-
- le = CG_AllocLocalEntity();
- re = &le->refEntity;
-
- le->leType = LE_FRAGMENT;
- le->startTime = cg.time;
- le->endTime = le->startTime + 5000 + random() * 3000;
-
- VectorCopy( origin, re->origin );
- AxisCopy( axisDefault, re->axis );
- re->hModel = hModel;
-
- le->pos.trType = TR_GRAVITY;
- VectorCopy( origin, le->pos.trBase );
- VectorCopy( velocity, le->pos.trDelta );
- le->pos.trTime = cg.time;
-
- le->bounceFactor = 0.3;
-
- le->leBounceSoundType = LEBS_BLOOD;
- le->leMarkType = LEMT_BLOOD;
- }
-
- /*
- ===================
- CG_GibPlayer
-
- Generated a bunch of gibs launching out from the bodies location
- ===================
- */
- #define GIB_VELOCITY 250
- #define GIB_JUMP 250
- void CG_GibPlayer( vec3_t playerOrigin ) {
- vec3_t origin, velocity;
-
- if ( !cg_blood.integer ) {
- return;
- }
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- if ( rand() & 1 ) {
- CG_LaunchGib( origin, velocity, cgs.media.gibSkull );
- } else {
- CG_LaunchGib( origin, velocity, cgs.media.gibBrain );
- }
-
- // allow gibs to be turned off for speed
- if ( !cg_gibs.integer ) {
- return;
- }
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibAbdomen );
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibArm );
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibChest );
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibFist );
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibFoot );
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibForearm );
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibIntestine );
-
- VectorCopy( playerOrigin, origin );
- velocity[0] = crandom()*GIB_VELOCITY;
- velocity[1] = crandom()*GIB_VELOCITY;
- velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
- CG_LaunchGib( origin, velocity, cgs.media.gibLeg );
-
- }
-
-